package com.quanyan.place.service.impl;

import com.alibaba.fastjson.JSON;
import com.quanyan.api.APIResponse;
import com.quanyan.common.Plugin.Page;
import com.quanyan.common.Plugin.PageObj;
import com.quanyan.common.constants.Constants;
import com.quanyan.common.enums.PlatformTypeEnum;
import com.quanyan.common.enums.SysParameterConfigEnum;
import com.quanyan.common.exception.BizException;
import com.quanyan.common.utils.DateTimeUtils;
import com.quanyan.common.utils.DateUtils;
import com.quanyan.common.utils.StringUtil;
import com.quanyan.orderpay.request.ReqOrderSave;
import com.quanyan.orderpay.request.ReqPayInfo;
import com.quanyan.orderpay.request.ReqProductDetail;
import com.quanyan.orderpay.response.RespPreOrder;
import com.quanyan.orderpay.service.OrderPayService;
import com.quanyan.pay.enums.OrderStatusEnum;
import com.quanyan.pay.enums.PayWayEnum;
import com.quanyan.place.biz.IBaseService;
import com.quanyan.place.client.BizPlaceClient;
import com.quanyan.place.constants.PlaceConstants;
import com.quanyan.place.entity.*;
import com.quanyan.place.entity.apireq.*;
import com.quanyan.place.entity.apiresp.*;
import com.quanyan.place.entity.vo.DictPlaceDataVo;
import com.quanyan.place.entity.vo.PlaceScanOrderPayVo;
import com.quanyan.place.entity.vo.RespPlaceRevenueStats;
import com.quanyan.place.enums.PlaceErrorCodeEnum;
import com.quanyan.place.mapper.*;
import com.quanyan.place.service.BaseService;
import com.quanyan.place.service.PlaceOrderCallbackService;
import com.quanyan.place.service.PlaceOrderService;
import com.quanyan.place.service.PlaceOrderSetterService;
import com.quanyan.user.serviceFacade.UserServiceFacade;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by liuyaoxin on 2017/1/5.
 * /第三方场馆订单结算模块
 */
@Service
public class PlaceOrderSetterServiceImpl implements PlaceOrderSetterService{


    @Autowired
    VPlaceSetterMapper setterMapper;

    @Autowired
    TbBizPlaceSetterDetailMapper setterDetailMapper;

    @Autowired
    TbSupplierMapper supplierMapper;

    @Autowired
    BaseService baseService;

    @Autowired
    OrderPayService orderPayService;

    @Autowired
    PlaceOrderCallbackService placeOrderCallbackService;

    @Autowired
    TbBizPlaceSetterDetailMapper tbBizPlaceSetterDetailMapper;

    @Autowired
    TbBizPlaceExtractRecordMapper tbBizPlaceExtractRecordMapper;

    @Autowired
    TbBizPlacePrivateOrderMapper tbBizPlacePrivateOrderMapper;

    /**
     * 结算合计
     * @param reqVo
     * @return
     */
    public BigDecimal getToalSetterAmount(ReqOrderSetterVo reqVo) {
        TbBizPlaceSetterDetailExample example2 = new TbBizPlaceSetterDetailExample();
        TbBizPlaceSetterDetailExample.Criteria criteria2 = example2.createCriteria();
        criteria2.andSupplierIdEqualTo(reqVo.getSupplierId());
        if (!org.springframework.util.StringUtils.isEmpty(reqVo.getPlaceName())) {
            criteria2.andPlaceNameLike("%" + reqVo.getPlaceName().trim() + "%");
        }
        if (reqVo.getCategoryId() != null) {
            criteria2.andCategoryIdEqualTo(reqVo.getCategoryId());
        }
        if (reqVo.getPlaceId() != null) {
            criteria2.andPlaceIdEqualTo((reqVo.getPlaceId()));
        }
        if (reqVo.getStartTime()!=null&&reqVo.getEndTime()!=null){
            criteria2.andOrderFinishTimeBetween(DateUtils.dayBegin(reqVo.getStartTime()),DateUtils.dayEnd(reqVo.getEndTime()));
        }
        if (!org.springframework.util.StringUtils.isEmpty(reqVo.getPlaceOrderId())){
            criteria2.andPlaceOrderIdLike("%"+reqVo.getPlaceOrderId()+"%");
        }
        List<TbBizPlaceSetterDetail> list = setterDetailMapper.selectByExample(example2);
        BigDecimal sumAmount=new BigDecimal("0");
        for (TbBizPlaceSetterDetail detail:list){
            sumAmount=sumAmount.add(detail.getSetterAmount());
        }
        return sumAmount;
    }

    /**
     * 订单结算列表
     * @param reqVo
     * @return
     */
    @Override
    public RespOrderSetterVo orderSetterList(ReqOrderSetterVo reqVo) {
        Integer pageNum = 0;
        Integer pageSize = Constants.DEFAULT_PAGE_SIZE;
        List<RespOrderSetterVo> respList = new ArrayList<>();
        TbBizPlaceSetterDetailExample example = new TbBizPlaceSetterDetailExample();
        TbBizPlaceSetterDetailExample.Criteria criteria = example.createCriteria();
        TbBizPlaceSetterDetailExample.Criteria criteria2 = example.createCriteria();
        pageNum = reqVo.getPageNum();
        pageSize = reqVo.getPageSize();

        criteria.andSupplierIdEqualTo(reqVo.getSupplierId());
        if (!org.springframework.util.StringUtils.isEmpty(reqVo.getPlaceName())) {
            criteria.andPlaceNameLike("%" + reqVo.getPlaceName().trim() + "%");
        }
        if (reqVo.getPlaceId() != null) {
            criteria.andPlaceIdEqualTo((reqVo.getPlaceId()));
        }
        if (reqVo.getCategoryId() != null) {
            criteria.andCategoryIdEqualTo(reqVo.getCategoryId());
        }
        if (reqVo.getStartTime()!=null&&reqVo.getEndTime()!=null){
            criteria.andOrderFinishTimeBetween(DateUtils.dayBegin(reqVo.getStartTime()),DateUtils.dayEnd(reqVo.getEndTime()));
        }
        if (!org.springframework.util.StringUtils.isEmpty(reqVo.getPlaceOrderId())){
            criteria.andPlaceOrderIdLike("%"+reqVo.getPlaceOrderId()+"%");
            criteria2.andSupplierIdEqualTo(reqVo.getSupplierId());
            criteria2.andOrderNoLike("%"+reqVo.getPlaceOrderId()+"%");
            if (!org.springframework.util.StringUtils.isEmpty(reqVo.getPlaceName())) {
                criteria2.andPlaceNameLike("%" + reqVo.getPlaceName().trim() + "%");
            }
            if (reqVo.getPlaceId() != null) {
                criteria2.andPlaceIdEqualTo((reqVo.getPlaceId()));
            }
            if (reqVo.getCategoryId() != null) {
                criteria2.andCategoryIdEqualTo(reqVo.getCategoryId());
            }
            if (reqVo.getStartTime()!=null&&reqVo.getEndTime()!=null){
                criteria2.andOrderFinishTimeBetween(DateUtils.dayBegin(reqVo.getStartTime()),DateUtils.dayEnd(reqVo.getEndTime()));
            }
            example.or(criteria2);
        }

        example.setOrderByClause("order_finish_time desc");
        int total = setterDetailMapper.countByExample(example);
        example.setPage(new Page(pageNum * pageSize, pageSize, total));
        List<TbBizPlaceSetterDetail> list = setterDetailMapper.selectByExample(example);
        for (TbBizPlaceSetterDetail vo : list) {
            RespOrderSetterVo resp = new RespOrderSetterVo();
            resp.setPlaceName(vo.getPlaceName());
            resp.setCategoryId(vo.getCategoryId());
            resp.setPlaceOrderId(vo.getPlaceOrderId());
            resp.setOrderType(vo.getOrderType());
            resp.setPayWay(vo.getPayWay());
            resp.setOrderFinishTime(vo.getOrderFinishTime());
            resp.setSetterTime(vo.getSetterTime());
            resp.setSetterAmount(vo.getSetterAmount());
            resp.setPaymentTime(vo.getPaymentTime());
            resp.setOrderNo(vo.getOrderNo());
            respList.add(resp);
        }
        PageObj<List<RespOrderSetterVo>> result = PageObj.create(total, pageNum, pageSize, respList);
        BigDecimal totalSettetAmount=new BigDecimal("0");
        totalSettetAmount=this.getToalSetterAmount(reqVo);
        //可以提现的余额
        List<TbBizPlaceSetterDetail> listVal= this.getSetterOrderDataBySupplierId(reqVo.getSupplierId(),0,null,null);
        BigDecimal totalAmount=new BigDecimal(0);
        for (TbBizPlaceSetterDetail detailVo:listVal){
            totalAmount=totalAmount.add(detailVo.getSetterAmount());
        }
        RespOrderSetterVo vo=new RespOrderSetterVo();
        vo.setResult(result);
        vo.setTotalSetterAmount(totalSettetAmount);//结算合计
        vo.setTotalAmount(totalAmount);
        return vo;
    }


    @Override
    public List<RespOrderSetterVo> getPlaceOrderData(ReqOrderSetterVo reqOrderSetterVo) {
        List<RespOrderSetterVo> list=setterMapper.getPlaceOrderData(reqOrderSetterVo);
        //根据场馆ID 取出可以结算的订单
        return list;
    }

    @Override
    public int saveSetterOrderData(TbBizPlaceSetterDetail vo) {
        return  tbBizPlaceSetterDetailMapper.insertSelective(vo);
    }

    /**
     * 获取要结算的订单数据
     * @param supplierId
     * @return
     */
    @Override
    public List<TbBizPlaceSetterDetail> getSetterOrderDataBySupplierId(Integer supplierId,Integer status,Date orderFinishStartTime ,Date orderFinishEndTime) {
        TbBizPlaceSetterDetailExample example =new TbBizPlaceSetterDetailExample();
        TbBizPlaceSetterDetailExample.Criteria criteria=example.createCriteria();
        if (supplierId!=null){
            criteria.andSupplierIdEqualTo(supplierId);
        }
        if (status!=null){
            criteria.andSetterStatusEqualTo(status);
        }
        if (orderFinishStartTime!=null&&orderFinishEndTime!=null){
            criteria.andOrderFinishTimeBetween(orderFinishStartTime,orderFinishEndTime);
        }
        example.setOrderByClause("order_finish_time asc");
        List<TbBizPlaceSetterDetail> list=tbBizPlaceSetterDetailMapper.selectByExample(example);
        return list;
    }

    @Override
    public int saveExtractRecordData(TbBizPlaceExtractRecord record) {
        return tbBizPlaceExtractRecordMapper.insertSelective(record);
    }

    @Override
    public int updateSetterOrderStatus(List<String> placeOrderIdList) {
        TbBizPlaceSetterDetailExample example =new TbBizPlaceSetterDetailExample();
        TbBizPlaceSetterDetailExample.Criteria criteria=example.createCriteria();
        criteria.andPlaceOrderIdIn(placeOrderIdList);
        TbBizPlaceSetterDetail  vo=new TbBizPlaceSetterDetail();
        vo.setSetterStatus(1);
        return setterDetailMapper.updateByExampleSelective(vo,example);
    }

    /**
     * 获得提现总金额
     * @param reqVo
     * @return
     */
    public BigDecimal getTotalExtractAmount(ReqExtractRecordVo reqVo){
        TbBizPlaceExtractRecordExample example2 = new TbBizPlaceExtractRecordExample();
        TbBizPlaceExtractRecordExample.Criteria criteria2 = example2.createCriteria();
        criteria2.andSupplierIdEqualTo(reqVo.getSupplierId());

        if (!org.springframework.util.StringUtils.isEmpty(reqVo.getExtractNo())) {
            criteria2.andExtractNoLike("%" + reqVo.getExtractNo().trim() + "%");
        }
        if (reqVo.getStartTime()!=null&&reqVo.getEndTime()!=null){
            criteria2.andExtractTimeBetween(DateUtils.dayBegin(reqVo.getStartTime()),DateUtils.dayEnd(reqVo.getEndTime()));
        }
        if (!org.springframework.util.StringUtils.isEmpty(reqVo.getRemark())){
            criteria2.andRemarkLike("%"+reqVo.getRemark()+"%");
        }
        List<TbBizPlaceExtractRecord> list= tbBizPlaceExtractRecordMapper.selectByExample(example2);
        BigDecimal sumAmount=new BigDecimal("0");
        for (TbBizPlaceExtractRecord record:list){
            sumAmount=sumAmount.add(record.getExtractAmount());
        }
        return sumAmount;
    }

    @Override
    public RespExtractRecordVo extractRecordList(ReqExtractRecordVo reqVo) {
        Integer pageNum = 0;
        Integer pageSize = Constants.DEFAULT_PAGE_SIZE;
        List<RespExtractRecordVo> respList = new ArrayList<>();
        TbBizPlaceExtractRecordExample example = new TbBizPlaceExtractRecordExample();
        TbBizPlaceExtractRecordExample.Criteria criteria = example.createCriteria();
        pageNum = reqVo.getPageNum();
        pageSize = reqVo.getPageSize();
        criteria.andSupplierIdEqualTo(reqVo.getSupplierId());

        if (!org.springframework.util.StringUtils.isEmpty(reqVo.getExtractNo())) {
            criteria.andExtractNoLike("%" + reqVo.getExtractNo().trim() + "%");
        }
        if (reqVo.getStartTime()!=null&&reqVo.getEndTime()!=null){
            criteria.andExtractTimeBetween(DateUtils.dayBegin(reqVo.getStartTime()),DateUtils.dayEnd(reqVo.getEndTime()));
        }
        if (!org.springframework.util.StringUtils.isEmpty(reqVo.getRemark())){
            criteria.andRemarkLike("%"+reqVo.getRemark()+"%");
        }
        example.setOrderByClause("id desc");
        int total = tbBizPlaceExtractRecordMapper.countByExample(example);
        example.setPage(new Page(pageNum * pageSize, pageSize, total));
        List<TbBizPlaceExtractRecord> list = tbBizPlaceExtractRecordMapper.selectByExample(example);
        for (TbBizPlaceExtractRecord vo : list) {
            RespExtractRecordVo resp = new RespExtractRecordVo();
            resp.setExtractNo(vo.getExtractNo());
            resp.setExtractTime(vo.getExtractTime());
            resp.setExtractAmount(vo.getExtractAmount());
            resp.setStatus(vo.getStatus());
            resp.setRemark(vo.getRemark());
            respList.add(resp);
        }
        PageObj<List<RespExtractRecordVo>> result = PageObj.create(total, pageNum, pageSize, respList);
        BigDecimal totalExtractAmount=this.getTotalExtractAmount(reqVo);
        //可以提现的余额
        List<TbBizPlaceSetterDetail> listVal= this.getSetterOrderDataBySupplierId(reqVo.getSupplierId(),0,null,null);
        BigDecimal setterTotalAmount=new BigDecimal(0);
        for (TbBizPlaceSetterDetail detailVo:listVal){
            setterTotalAmount=setterTotalAmount.add(detailVo.getSetterAmount());
        }
        RespExtractRecordVo vo=new RespExtractRecordVo();
        vo.setResult(result);
        vo.setTotalExtractAmount(totalExtractAmount);//提现合计
        vo.setTotalAmount(setterTotalAmount);
        return vo;
    }

    @Override
    public  List<TbSupplier> getPlaceSupplier(ReqBusinessAccountVo reqBusinessAccountVo, boolean flag) {
        if (flag){
            Page page=new Page();
            page.setBegin(reqBusinessAccountVo.getPageNum() * reqBusinessAccountVo.getPageSize());
            page.setEnd(reqBusinessAccountVo.getPageSize());
            reqBusinessAccountVo.setPage(page);
        }else{
            reqBusinessAccountVo.setPage(null);
            reqBusinessAccountVo.setPageNum(null);
            reqBusinessAccountVo.setPageSize(null);
        }
        //reqBusinessAccountVo.setPage(new Page(reqBusinessAccountVo.getPageNum() * reqBusinessAccountVo.getPageSize(), reqBusinessAccountVo.getPageSize(), total));
        return setterMapper.getPlaceSupplier(reqBusinessAccountVo);
    }

    @Override
    public List<TbBizPlaceExtractRecord> getExtractRecordListBySupplierId(Integer supplierId, List<Integer> value,Date payStartTime,Date payEndTime) {
        TbBizPlaceExtractRecordExample example =new TbBizPlaceExtractRecordExample();
        TbBizPlaceExtractRecordExample.Criteria criteria=example.createCriteria();
        criteria.andSupplierIdEqualTo(supplierId);
        if (value!=null){
            criteria.andStatusIn(value);
        }
        if (payStartTime!=null&&payEndTime!=null){
            criteria.andPayTimeBetween(payStartTime,payEndTime);
        }
        return tbBizPlaceExtractRecordMapper.selectByExample(example);
    }

    @Override
    public int getPlaceSupplierCount(ReqBusinessAccountVo reqBusinessAccountVo) {
        return  setterMapper.getPlaceSupplierCount(reqBusinessAccountVo);
    }

    @Override
    public TbSupplier getBankAccountBySupplierId(Integer supplierId) {
        TbSupplier supplier=supplierMapper.selectByPrimaryKey(supplierId);
        return supplier;
    }

    @Override
    public TbBizPlaceSetterDetail getMinOrMaxSetterDetailData(boolean flag,Integer status) {
        TbBizPlaceSetterDetailExample example =new TbBizPlaceSetterDetailExample();
        TbBizPlaceSetterDetailExample.Criteria criteria=example.createCriteria();
        if (flag){
            if (status!=null){
                criteria.andSetterStatusEqualTo(status);
            }
            example.setOrderByClause("setter_time desc");
        }else {
            if (status!=null){
                criteria.andSetterStatusEqualTo(status);
            }
            example.setOrderByClause("setter_time asc");
        }
        List<TbBizPlaceSetterDetail> list= setterDetailMapper.selectByExample(example);
        if (list!=null&&list.size()>0){
            return list.get(0);
        }else{
            return null;
        }
    }

    @Override
    public int updateExtractInfoByExtractNo(ExtractCallBackVo extractVo) {
        TbBizPlaceExtractRecordExample example =new TbBizPlaceExtractRecordExample();
        TbBizPlaceExtractRecordExample.Criteria criteria=example.createCriteria();
        criteria.andExtractNoEqualTo(extractVo.getExtractNo());
        TbBizPlaceExtractRecord vo=new TbBizPlaceExtractRecord();
        vo.setPayTime(extractVo.getPayTime());
        vo.setStatus(extractVo.getStatus());
        return tbBizPlaceExtractRecordMapper.updateByExampleSelective(vo,example);
    }

    @Override
    public TbBizPlacePrivateOrder getOrderNoById(Integer id) {
        TbBizPlacePrivateOrder vo= tbBizPlacePrivateOrderMapper.selectByPrimaryKey(id);
        return vo;
    }

}

